6. A simulation that targets a specific outcome#

In normal model use, the trajectory of the exogenous variables determine the trajectory of the endogenous (left hand side) variables. However, sometimes it can be useful to reverse the causality in the model, to find a trajectory for some exogenous variables that will result in some endogenous variables achieving specific values.

A simple example might be where a policy maker wants to know what level of Carbon Tax, if implemented in a budget neutral fashion, would be needed to achieve a specific level of emissions. As specified, the analytical question is to achieve two targets:

  1. A specific \(CO^2\) emissions trajectory

  2. An unchanged fiscal deficit

6.1. targetting in modelflow#

Targeting in Modelflow requires that there be as many instruments as there are targets. So in the above example two instruments would be required.

The instrument to achieve the emissions could be a Carbon tax (applied uniformly on emissions from coal, gas and crude oil). The instrument to achieve an unchanged fiscal deficit, could be government spending or another from of revenue, say taxes on labor.

To illustrate targetting a climate-aware model of Pakistan (Burns et al. [2021]) is used.

To run the simulation, the following main steps must be undertaken

  1. Load a model and data

  2. Create a baseline

  3. Define instrument variables (one instrument can consist of several variables).

  4. Define a dataframe with the trajectory of the target variables.

  5. Solve the problem using the .invert method.

  6. Visualize the results

6.2. Load a model, data and descriptions#

We begin by loading the model file pak.pcim. This file contains the model object for the Pakistan model ised in Burns (2021), including all of the equations data and variables.

mpak,initial = model.modelload('../models/pak.pcim')
file read:  C:\mflow\papers\mfbook\content\models\pak.pcim

6.3. Solve the model to create a baseline#

As a first step we solve the model, using the initial dataframe that was generated on the modelload. In this instance, we solve the model from 2022 through 2100, and use (for the first-time) the option ljit=True. This option tells the model object to compile the model. Model compilation takes time, but once a model is compiled it will solve faster. An uncompiled model must organize the mathematics of the model “on-the-fly”. Compilation does this step in advance, so that when the model is solved it can be done so much more quickly.

When a model will be solved multiple times, the additional time required to compile the model, can be made up by the faster execution time each time the model is solved. Targetting requires the model to be solved many times, which makes the additional overhead of compilation worthwhile.

baseline = mpak(initial,2022,2100,alfa=0.7,silent=1,ljit=True)
mpak.basedf = baseline.copy()

6.4. Target CO2 emission - a very simple example#

To illustrate the process for solving the model in targetting mode, we start with a very simple example, where only the emission is targeted, and the objective is to have emissions grow at an annual rate of 1 percent.

6.4.1. Define targets#

Having loaded the model, created a baseline and designated the target (steps 1-3 from above), the next step is to create the target variable(s). We do so by defining two series: the first target_before_simple we set equal to the value of the total emissions variable PAKCCEMISCO2TKN in the baseline; the second target_simple is our target for the same variable, which we define using the .upd() method as the target_before_simple variable through 2024 and then having that variable grow slowly at 1 percent per year afterwards.

# Create dataframe with only the target variable 
target_before_simple = baseline.loc[2024:2100,['PAKCCEMISCO2TKN']]    

# create a target dataframe with a projection of the target variable 
target_simple = target_before_simple.upd(f'<2025 2100> PAKCCEMISCO2TKN =growth 1')

6.4.2. Define instruments#

The next step is to define the instruments, and in this case we will designate the three carbon taxes in the model as our instruments. We then create a list instruments_simple comprised of their mnemonics.

instruments_simple = [['PAKGGREVCO2CER','PAKGGREVCO2GER', 'PAKGGREVCO2OER']]

6.4.3. Finding the values for the instruments that achieve the desired target#

To find the value for the instruments that achieves are target of a 1 percent growth in emissions, we use the modelflow .invert() method. Passing it the baseline database, the target dataframe that we defined above and the list of the instruments to use.

The .invert() method will solve the model 77 times (once each for each year to be solved), and will solve the model multiple times for each year until it finds a set of instrument values that result in the desired targets. The dataframe containing the solution to the targeting problem is returned by the .invert() method and also stored in the .lastdf internal dataframe.

6.4.3.1. Invert options#

The .invert() method has many options. The first three define the problem, the remainder influence how the the solver operates. Finding the right options for a given problem is not always straightforward. The following table provides some hints on how to work with these options to optimize solution speed for a given problem.

invert(self, databank, targets, instruments, silent=1, DefaultImpuls=0.01, defaultconv=0.001, nonlin=False, maxiter=30, delay=0, varimpulse=False, progressbar=True, debug=False)

option

parameters

Explanation

databank

name of dataframe

Dictates the initial conditions of the model (same as in a normal solve)

targets

list

A list of the variables to be targeted

instruments

list

A list of the variables that will be used as instruments to achieve the targets. Individual targets may have multiple instruments (see example later in this chapter). Insstyrument list may contain Impulse parameters specific to the instrument (see below).

silent

True:False

True: Suppress detailed outputs; False: Show detailed outputs (one line per iteration per year)

DefaultImpuls

float

Determines the size of the change in instruments as the model searches for answers. Choose a value relative to the size of the actual series being modified.

defaultconv

float

Specifies the amount by which targeted variables may deviate from the target value and still be considered a solution. Should reflect the size of the target.

delay

Integer

Causes the instrument value changed to be lagged N periods from the target period being solved; For WBG models this should almost always be 0

varimpulse

True:False

True:Sets the initial change in the instrument for the future to the same as in the most recently solved period. This will greatly speed solves where instruments are expected to evolve in a smoothly (grow or be stable).

nonlin

Integer

N: Jacobian will be updated after N iterations without a solution; Most WBG models are near-linear so setting to 0 will solve faster. If the solution fails, try non-linear=5

maxiter

integer

Maximum number of Newton iterations; If passed model will fail with a non-convergence error. If model does not converge try with nonlin=False

6.4.3.2. Multiple instruments for one target#

While there must be at least one instrument for each target it is possible to have more than one instrument for a given target. Moreover, it is possible to assign specific impulse defaults to different instruments, or different weights for different instruments when there is a multi-instrument specification.

Below are specific illustrations of how the instrument list can be specified.

Type

Code

Explanation

Single Target; Single Instrument

instr=[‘Myvar’]

The instrument list includes only one variable

3 Targets; 3 Instruments

instr=[‘Myvar1’,’Myvar2’,’Myvar3’]

Each target has a specific instrument specified.

2 Targets; 2 Instruments; different impulse specifications

instr=[(‘Myvar1’,0.7),(‘Myvar2’.2000)]

The first instrument takes an impulse value of 0.7 (presumably because its values are relatively small). The second takes a much larger impulse value of 2000, reflecting its larger scale.

2 Targets; 3 Instruments for first target; 1 instrument for second

instr=[[‘Myvar1’,’myvar2’],’Myvar3’)]

The first instrument takes two instruments: Myvar1 and Myvar2; the second instrument has just one instrument: MyVar3

1 Target; 3 Instruments for first target, with different weights

instr=[[(‘Myvar1’,50),(‘myVar2’,25),(‘Myvar3’,10)]]

Three instruments are defined, each is assigned a weight, such that in finding values to achieve the target, ‘MyVar’ will be pertubed twice as much as myvar2 and 5 times as much as MyVar3

1 Target; 3 Instruments for first target, with different weights

instr=[[(‘Myvar1’,0.5),(‘myVar2’,0.25),(‘Myvar3’,0.10)]]

Three instruments are defined, each is assigned a weight, such that in finding values to achieve the target, ‘MyVar’ will be pertubed twice as much as myvar2 and 5 times as much as MyVar3

Note

The final section of this chapter explains in more detail the solution algorithm of the invert(0) method and the meaning of the various options of the method.

simple = mpak.invert(baseline,                  # Invert calls the target instrument device                   
                targets = target_simple,                   
                instruments=instruments_simple,
                
                DefaultImpuls=20,      # The default impulse instrument variables 
                defaultconv=2000.0,    # Convergergence criteria for targets
                varimpulse=True,      # Changes in instruments in each iteration are carried over to future iteratons
                nonlin=3,              # If no convergence after 3 iteration recalculate jacobi 
                silent=True,              # Don't show iteration output (try 1 for showing)
                maxiter = 3000,
                progressbar = True)

6.4.4. Display result#

Once the simulation is complete the results are as usual stored in the internal .basedf and .lastdf dataframes. Results can be inspected either by using tables or graphically.

Below we use the .plot_alt() method to compare the total emissions and the carbon taxes from the solution set and the initial baseline, first in levels and then in growth rates.

with mpak.set_smpl(2020,2100):    # change if you want another  timeframe 
    fig = mpak[f'PAKCCEMISCO2TKN' ].pct.plot_alt(title='Pakistan CO2 emission') 
../../_images/710a55af50764388b1379485fc53b5ee74dedc6f4832b627de3c3ce6eadcc80e.png
mpak['PAKCCEMISCO2?KN'].difpctlevel.mul100.plot(title="Emissions: slow growth of emissions to 1% per annum",showfig=True)
../../_images/b080778c1d55b7b2829560534adb5783bd692960a562fa67835b111379c2c429.png ../../_images/fe8c7d52a714530e3ac1f417553af1afd7ddc6011fceb9d682253d1fe6e9e57e.png
with mpak.set_smpl(2020,2100):    # change if you want another  timeframe 
    fig = mpak[f'PAKCCEMISCO2TKN'].plot_alt(title='Pakistan CO2 emission') 
    fig2 = mpak[f'PAKGGREVCO2CER'].plot_alt(title=f'Pakistan, tax rate requried to achieve slower emissions growth'); 
../../_images/c88ae8c1baec3783e280bfda53e0d23ee8126252cba4df8cc5a8bf456c35499e.png ../../_images/b9bcb0d0c5762e03d787997cfe53248416d6441098b24f5376fa97dc2047c95d.png
with mpak.set_smpl(2020,2100):
    print(mpak['PAKCCEMISCO2TKN'].difpctlevel.
          mul100.plot(title="Percent change in emissions"))
    
    
# change if you want another  timeframe 
#fig = mpak[f'PAKCCEMISCO2TKN' ].plot_alt(title='Pakistan CO2 emission') 
#fig2 = mpak[f'PAKGGREVCO2CER' ].plot_alt(title=f'Pakistan, taxes for coal, oil and gas are the same'); 
../../_images/4d0e731cf73153d5280983eb2dd9c7918c9851995ea849f039c4dc31d431a9f0.png
Figure(1000x200)

6.5. Targeting carbon emissions in a budget neutral manner#

In this example we find the levels of carbon tax and government spending on investment goods that are consistent with 1 percent growth in emissions and an unchanged fiscal deficit.

We have two targets (the fiscal deficit and emissions) and must define at least two instruments, in this case:

  1. The carbon emissions target will be determined by 3 variables (carbon taxes on cooal, oil and natural gas)

  2. The fiscal balance target will be met by one instrument Government spending on goods and services, implying that revenues from the Carbon Taxes will be used to increase government services.

Burns et al.(2021), using the same model explores, the macroeconomic consequences implications of alternative uses of the revenues from the Carbon Tax.

Note

there is no technical restriction on what instruments to choose, HJowever,if instruments are chosen that have little influence on the targets, modelflow is unlikely to find values for the instruments that achieve the desired levels of the target variables.

6.5.1. Define target trajectory for CO2 emission.#

The objective is to reduce Carbon emissions by 40% (as compared with the baseline) by the year 2050 and hold them constant in level terms afterwards.

The two variables below define these objectives. Changing them would allow the same code to be used to explore how different emission targets and different years in which the target should be fulfilled affect the results.

reduction_percent = 40  # Input the desired reduction in percent. 
achieved_by       = 2050

If as here, our target is to achieve a 40 percent reduction in emissions by 2050, we need to:

  1. Calculate the level of emissions to be reached in the target year as \(PAKCCEMISCO2TKN_{2050} (1-40/100)\)

  2. Calculate the growth rate of the target variable needed to reach that level in 2050=
    \(\dfrac{PAKCCEMISCO2TKN_{2050} (1-40/100)}{PAKCCEMISCO2TKN_{2024}}^{\dfrac{1}{2050-2024}}-1\)

  3. Calculate target values for emission in each year and then hold them constant from target year through 2100

bau_emissions_final = baseline.loc[achieved_by,'PAKCCEMISCO2TKN'] #baseline emissions in 2050
bau_emissions_2024  = baseline.loc[2024,'PAKCCEMISCO2TKN'] #baseline emissions in 2024

target_emissions_final  = bau_emissions_final*(1-reduction_percent/100) #target emissions in 2050

#growth rate needed between 2024 and 2050 to reach the target emissioons level in 2050
target_growth_rate  = (target_emissions_final/bau_emissions_2024)**(1/(achieved_by-2024))-1
bau_growth_rate     = (bau_emissions_final/bau_emissions_2024)**(1/(achieved_by-2024))-1

print(f"Baseline Emissions in {achieved_by}               : {bau_emissions_final:13,.0f} tons")
print(f"Target  Emissions  in {achieved_by}               : {target_emissions_final:13,.0f} tons")
print(f"Business as usual growth rate in percent : {bau_growth_rate:13,.1%}")
print(f"Target growth rate in percent            : {target_growth_rate:13,.1%}")
Baseline Emissions in 2050               :   439,930,556 tons
Target  Emissions  in 2050               :   263,958,334 tons
Business as usual growth rate in percent :          2.5%
Target growth rate in percent            :          0.5%

6.5.2. Create a dataframe with the target emissions#

op prepare the simulation we need a dataframe with the target variable set to the desired growth path, calculated above.

This target dataframe should only contain series for the target variables, at this stage just one.

First, we create a series for the target variable that is a copy of its values in th baseline. Next we set it to the levels desired by growing it at the growth rate calculated above between the initial year and the target year. Then we hold emissions constant at this level.

# Create dataframe with only the target variable (data defined from 2024 onwards)
target_before = baseline.loc[2024:,['PAKCCEMISCO2TKN']]     
# create a target dataframe with a projection of the target variable 
target = target_before.upd(f'<2025 {achieved_by}> PAKCCEMISCO2TKN =growth {100*target_growth_rate}')
target = target.upd(f'<{min(2100,achieved_by+1)} {2100}> PAKCCEMISCO2TKN = {target_emissions_final}')
#target.loc[:2055]

6.5.3. Create target for government deficit#

We also need to add to the target dataframe a series containing our target for the government deficit. As our objective is to hold the deficit constant as a share of GDP (at the levels in the baseline), we just copy the relevant series into the target dataframe.

target.loc[:,'PAKGGBALOVRLCN_'] = baseline.loc[2022:2100,'PAKGGBALOVRLCN_']
target
PAKCCEMISCO2TKN PAKGGBALOVRLCN_
2024 2.303703e+08 -3.131896
2025 2.315794e+08 -3.045253
2026 2.327948e+08 -2.984815
2027 2.340166e+08 -2.945600
2028 2.352449e+08 -2.921505
... ... ...
2096 2.639583e+08 -2.540508
2097 2.639583e+08 -2.540567
2098 2.639583e+08 -2.540636
2099 2.639583e+08 -2.540713
2100 2.639583e+08 -2.540798

77 rows × 2 columns

target.plot(title = 'Target values for CO2 Emission and deficit');
../../_images/56049a0e79d5da285d99d546a8757c6de7b2e59a00cfa8af9a4df0d738a0520a.png

6.6. Define instruments#

The instruments to achieve these targets are the 3 carbon taxes and government spending on goods and services. To find the mnemonics for these variables a search is done over the descriptions of the variables, first over the carbon tax:

mpak['!*Carbon*'].des
PAKGGREVCO2CER : Carbon tax on coal (USD/t)
PAKGGREVCO2GER : Carbon tax on gas (USD/t)
PAKGGREVCO2OER : Carbon tax on oil (USD/t)

A separate search is done to identify the government spending variable to be used as an instrument. It makes sense to use a variable which has a fairly direct impact on the government deficit.

mpak['!*government*expenditure*goods*'].des
PAKGGEXPGNFSCN        : General government expenditure on goods and services (millions lcu)
PAKGGEXPGNFSCN_A      : Add factor:General government expenditure on goods and services (millions lcu)
PAKGGEXPGNFSCN_D      : Fix dummy:General government expenditure on goods and services (millions lcu)
PAKGGEXPGNFSCN_FITTED : Fitted  value:General government expenditure on goods and services (millions lcu)
PAKGGEXPGNFSCN_X      : Fix value:General government expenditure on goods and services (millions lcu)

For the purposes of this experiment the PAKGGEXPGNFSCN_A variable (the add-factor for the government spending on goods and services equation) is selected.

We then create a list called instruments that is populated with two sets, the first a list of instruments for the first target and the second a list of one instruments for the second target.

instruments = [['PAKGGREVCO2CER','PAKGGREVCO2GER', 'PAKGGREVCO2OER'],
               'PAKGGEXPGNFSCN_A']   

In total there are two instruments and two targets (although one instrument is actually a list of three instruments), which satisfies the constraint that there must be exactly as many instruments as targets.

6.7. Now solve the problem:#

Now we have a dataframe with target values and a list of instrument variables. We are ready to solve the problem.

%%time
unweighted= mpak.invert(baseline,                  # Invert calls the targeting routine 
                targets = target.loc[:,: ],        #our targets defined above           
                instruments=instruments,           # our instruments defined above
                DefaultImpuls=20,                  # The default impulse value for the instruments 
                defaultconv=2000.0,                # Convergergence criteria for targets ( a relatively large number)
                varimpulse=True,                   # Change in instruments after each iteration are carried over to the future
                nonlin=5,                          # If no convergence in 15 iteration recalculate jacobi 
                silent=True,                       # Don't show iteration output (try 1 for showing)
                delay=False,
                maxiter = 75,
                progressbar = True)

6.7.1. Results#

The following two chart illustrate that the objective of slowing emissions growth was achieved, with the growth rate in the targeted series equal to 1 percent.

with mpak.set_smpl(2020,2100):
    mpak['PAKCCEMISCO2TKN'].plot_alt(title='Emissions: baseline versus target') #this uses the values of the baseline
          
../../_images/e063273aafba3aa5e7bfcdb5928002dabb79e0767606d816da12b3b778d5977a.png
import matplotlib.pyplot as plt

df=pd.DataFrame()
df['Baseline'] = mpak.basedf.loc[2020:2100,'PAKCCEMISCO2TKN'].pct_change(periods=1)*100
df['Scenario'] = mpak.lastdf.loc[2020:2100,'PAKCCEMISCO2TKN'].pct_change(periods=1)*100
plt.plot(df)

# set y label
plt.ylabel('Annual rate of growth')
# set x label
plt.xlabel('Time')
plt.legend(df.columns)
# set title
plt.title('Emissions growth rate baseline vs scenario')
# display plot
plt.show()
../../_images/80cdf5d7834438710ca8cad805a3068b30d0e4afbe1f2bae218f475d485f2b2c.png

Below the carbon tax that was required to achieve the desired emissions result.

with mpak.set_smpl(2020,2100):
    mpak['PAKGGREVCO2CER'].plot_alt(title='Carbon tax on coal: baseline versus target ')
../../_images/565a0d784c5462a28eaabcc0c3d95849950f81040fc5a9d866bb7653e7369603.png

6.8. Weighting the instruments#

When using multiple instruments for a single target, the modeler may want to privilege changes in one instrument over another by specifying weights to attach to each. In the example below, specific weights are attached to the instruments, instructing the solver to place twice as much emphasis on adjusting the carbon tax on coal emissions (as compared with the other two carbon taxes).

new_instruments =[[('PAKGGREVCO2CER',50),
                   ('PAKGGREVCO2GER', 25),
                   ('PAKGGREVCO2OER',25)],
                 'PAKGGEXPGNFSCN_A']

weighted = mpak.invert(baseline,                  # Invert calls the target instrument device                   
                targets = target.loc[:,: ],                   
                instruments=new_instruments,
                DefaultImpuls=20,              # The default impulse instrument variables 
                defaultconv=2000.0,              # Convergergence criteria for targets
                varimpulse=True,             # Changes in instruments in each iteration are carried over to the future
                nonlin=5,                    # If no convergence in 15 iteration recalculate jacobi 
                silent=1,                     # Don't show iteration output (try 1 for showing)
                delay=0,
                maxiter = 50,
                progressbar = True)

With a weight twice as large on the coal carbon tax instrument, the carbon tax on coal rises to a level twice as high as that of the other carbon sources.

with mpak.set_smpl(2020,2100):    # change if you want another  timeframe 
    fig = mpak[f'PAKGGREVCO2CER PAKGGREVCO2GER PAKGGREVCO2OER' ].plot(title='Carbon taxes in weighted-target scenario ') 
    
../../_images/1078ee35baf2adc917ec63b20058006ebd227ea22720319fb136f29d30e19fcc.png

6.9. Targeting background#

The concept of targets and instruments in economic modeling was introduced by Tinbergen [1967]

When solving a targeting problem it can be thought as follows: From the generic description of a model: \(\textbf{y}_t= \textbf{F}(\textbf{x}_{t})\). Here \(\textbf{x}_{t}\) are all predetermined variables - lagged endogenous and all exogenous variables.

Think of a condensed model (\(\textbf{G}\)) with a few endogenous variables (\(\bar{\textbf{y}}_t\)): the targets and a few exogenous variables(\(\bar{\textbf{x}}_{t}\)): the instrument variables. All the rest of the predetermined variables are fixed:
\(\bar{\textbf{y}}_t= \textbf{G}(\bar{\textbf{x}}_{t})\)

In some models the result depends on the level of exogenous variables with a lag. For instance in a disease spreading model, the number of infected on a day depends on the probability of transmission some days before. If the probability of transmission is the instrument and the number of infected is the target. Therefor it can be useful to allow a delay, when finding the instruments. In this case we want to look at \(\textbf{y}_t= \textbf{F}(\textbf{x}_{t-delay})\)

If we invert G we have a model where instruments are functions of targets: \(\bar{\textbf{x}_{t-delay}}= \textbf{G}^{-1}(\bar{\textbf{y}_{t}})\). Then all we have to do is to find \(\textbf{G}^{-1}(\bar{\textbf{y}_{t}})\)

For most models \(\bar{\textbf{x}}_{t-delay}= \textbf{G}^{-1}(\bar{\textbf{y}_{t}})\) do not have a nice close form solution. However it can be solved numerically. We turn to Newton–Raphson method.

So \(\bar{\textbf{x}}_{t-delay}= \textbf{G}^{-1}(\bar{\textbf{y}_{t}^*})\) will be found using :

for \(k\) = 1 to convergence

\(\bar{\textbf{x}}_{t-delay,end}^k= \bar{\textbf{x}}_{t-delay,end}^{k-1}+ \textbf{J}^{-1}_t \times (\bar{\textbf{y}_{t}^*}- \bar{\textbf{y}_{t}}^{k-1})\)

\(\bar{\textbf{y}}_t^{k}= \textbf{G}(\bar{\textbf{x}}_{t-delay}^{k})\)

convergence: \(\mid\bar{\textbf{y}_{t}^*}- \bar{\textbf{y}_{t}} \mid\leq \epsilon\)

Now we just need to find:

\(\textbf{J}_t = \frac{\partial \textbf{G} }{\partial \bar{\textbf{x}}_{t-delay}}\)

ModelFlow uses numerical differentiation, as it is quite simple and fast.

\(\textbf{J}_t \approx \frac{\Delta \textbf{G} }{\Delta \bar{\textbf{x}}_{t-delay}}\)

That means that we should run the model one time for each instrument, and record the impact on each of the targets from the , \({\Delta {x}_{t-delay}^{instrument}}\)then we have \(\textbf{J}_t\)

In order for \(\textbf{J}_t\) to be invertible there has to be the same number of targets and instruments.

However, each instrument can be a basket of exogenous variable an they can have different impulse \(\Delta\) .

(6.1)#\[\begin{equation} \Delta x^{instrument=i} = \begin{bmatrix} \Delta x^{instrument=i,variable=1} \\ \Delta x^{instrument=i,variable=2} \\ \Delta x^{instrument=i,variable=3} \\ \vdots \\ \Delta x^{instrument=i,variable=n} \\ \end{bmatrix} \end{equation}\]

When a instrument changes the variables wil change and the change will be in the proportions defined by their impulse.

You will notice that the level of \(\bar{\textbf{x}}\) is updated (by \(\textbf{J}^{-1}_t \times (\bar{\textbf{y}_{t}^*}- \bar{\textbf{y}_{t}}^{k-1})\)) in all periods from \(t-delay\) to \(end\), where \(end\) is the last timeframe in the dataframe. This is useful for many applications, where the instruments are level variable (i.e. not change variables). This is the default behavior. It can be changed.

6.10. Tuning the target input to get a result#

Models implemented in modelflow can be very different, and the targeting routine .invert is fairly general. In most cases, targetingwill not work out of the box, its options will have to be tweaked to fit the problem at hand.

6.10.1. Targetting options#

The invert options that affect the speed and accuracy of a solution are: the following:

DefaultImpuls defaultconv nonlin
maxiter
varimpulse

6.10.2. defImpuls#

As noted above, the impulse variable determines the size of the delta that is used to calculate the jacobian matrix: if it is too small or too large the resulting jacobian will solve only very slowly. Typically the impulse should be scaled in relation to the magnitude of the instrument it is to impact. As noted above, separate impulse values can be set for each instrument.

If a large impulse is used for a small variable (or a small impulse for a large variable) \(\textbf{x}+{\Delta \bar{\textbf{x}}_{t-delay}}\) the model may become unsolvable.

6.10.3. Nonlinearity#

If the model is nonlinear it makes sense to re-estimate the jacobian matrix \(\textbf{J}_t\) frequently. The nonlin=a number option allows the user to set the number of iterations the solver should allow without finding a solution before calculating a new jacobian.

If:

  • nonlin=0 the jacobi will not be updated (default)

  • nonlin=<a number> the same jacobi matrix will be updated every iterations

6.10.4. Convergence#

The targeting is stopped when all target variables converge. The convergence criteria should reflect the size of the target variables. Too large and the solution may not actually reflect a cl;ose approximation of the target, too small and the model may take a very long-time to solve.

  • defaultconv=<a number>

6.10.5. Maximum number of iterations#

  • maxiter=<a number>

This option determines the maximum number of iterations that the model should run in trying to find a solution. Reasonable initial numbers may be between 50 and 100. If a model takes more than 100 iterations, there may be an issue. Potentially the chosen instruments do not have much impact on the target variables, or the model is relatively non-linear. Try setting nonlin=10 to see if recalculating the Jacobian allows the model to solve.

6.11. Definition of Instruments#

As noted above there must be atleast one instrument for each target. Instruments are passed as a python list.

Each element in the list is an instrument.

  • An element can be:

    • a variable name

    • a tuple with a variable name and an associated impulse \(\Delta\)

    • a inner list which defines which contains:

      • a list of variable names. Each element in the inner list is an instrument variable

      • a list of tupls each tuple contains a variable name and the associated impulse \(\Delta\).

The \(\Delta\) variable(s) is (are) used in the numerical differentiation. Also if one instrument contains several variables, the proportion of each variable will be determined by the relative \(\Delta variable\).

The table below reproduces the one presented earlier.

Type

Code

Explanation

Single Target; Single Instrument

instr=[‘Myvar’]

The instrument list includes only one variable

3 Targets; 3 Instruments

instr=[‘Myvar1’,’Myvar2’,’Myvar3’]

Each target has a specific instrument specified.

2 Targets; 2 Instruments; different impulse specifications

instr=[(‘Myvar1’,0.7),(‘Myvar2’.2000)]

The first instrument takes an impulse value of 0.7 (presumably because its values are relatively small). The second takes a much larger impulse value of 2000, reflecting its larger scale.

2 Targets; 3 Instruments for first target; 1 instrument for second

instr=[[‘Myvar1’,’myvar2’],’Myvar3’)]

The first instrument takes two instruments: Myvar1 and Myvar2; the second instrument has just one instrument: MyVar3

1 Target; 3 Instruments for first target, with different weights

instr=[[(‘Myvar1’,50),(‘myVar2’,25),(‘Myvar3’,10)]]

Three instruments are defined, each is assigned a weight, such that in finding values to achieve the target, ‘MyVar’ will be pertubed twice as much as myvar2 and 5 times as much as MyVar3

1 Target; 3 Instruments for first target, with different weights

instr=[[(‘Myvar1’,0.5),(‘myVar2’,0.25),(‘Myvar3’,0.10)]]

Three instruments are defined, each is assigned a weight, such that in finding values to achieve the target, ‘MyVar’ will be pertubed twice as much as myvar2 and 5 times as much as MyVar3